package com.rockcent.mall.controller;

import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.RDateFormatUtils;
import com.rockcent.common.utils.RDateUtils;
import com.rockcent.helper.SysMessageHelper;
import com.rockcent.mall.Routes;
import com.rockcent.mall.lib.constants.SysMessageConstants;
import com.rockcent.mall.lib.domain.MerchantWithdraw;
import com.rockcent.mall.lib.domain.MerchantBank;
import com.rockcent.mall.lib.domain.MerchantFund;
import com.rockcent.mall.lib.domain.WithdrawEvent;
import com.rockcent.mall.lib.domain.enumclass.WithdrawCrowd;
import com.rockcent.mall.lib.domain.enumclass.WithdrawStatus;
import com.rockcent.mall.lib.dto.MerchantWithdrawDto;
import com.rockcent.mall.lib.dto.UserInfoDto;
import com.rockcent.mall.lib.helper.BaseUserHelper;
import com.rockcent.mall.lib.repository.MerchantWithdrawRepository;
import com.rockcent.mall.lib.repository.MerchantBankRepository;
import com.rockcent.mall.lib.repository.MerchantFundRepository;
import com.rockcent.mall.lib.repository.WithdrawEventRepository;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;

/**
 * Created by DK on 16/12/12.
 * 申请提现管理模块
 */
@RestController
public class MerchantApplyWithdrawController extends BaseController{

    private final Logger log = LoggerFactory.getLogger(MerchantApplyWithdrawController.class);

    @Autowired
    private BaseUserHelper userHelper;

    @Autowired
    private MerchantBankRepository merchantBankRepository;

    @Autowired
    private MerchantFundRepository merchantFundRepository;

    @Autowired
    private MerchantWithdrawRepository merchantWithdrawRepository;

    @Autowired
    private WithdrawEventRepository withdrawEventRepository;

    /**
     * @api {post} /merchant/apply/withdraw 申请提现
     * @apiGroup MERCHANT_WITHDRAW
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} bankNo 银行卡号
     * @apiParam {BigDecimal} amount 提现金额
     * @apiParam {String} bankName 银行名称
     * @apiParam {String} bankAccountName 开户名
     * @apiParam {String} bankBranchName <code>必传参数</code> 开户银行支行银行名称
     *
     * @apiSuccessExample { json } Success-Response:
     * {
     *  "code": "1",
     *  "desc": "成功"
     *  }
     */
    @Transactional
    @RequestMapping(value = Routes.MERCHANT_APPLY_WITHDRAW, method = RequestMethod.POST)
    public JsonResult applyWithdraw (HttpServletRequest request, @RequestBody MerchantWithdrawDto dto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            String bankAccountName = dto.getBankAccountName();
            if (StringUtils.isBlank(bankAccountName)) {
                jsonResult.remind("开户名 不能为空",log);
                return;
            }
            String bankBranchName = dto.getBankBranchName();
            if (StringUtils.isBlank(bankBranchName)) {
                jsonResult.remind("支行银行名称 不能为空",log);
                return;
            }
            String bankName = dto.getBankName();
            if (StringUtils.isBlank(bankName)) {
                jsonResult.remind("银行名称 不能为空",log);
                return;
            }

            String dtoBankNo = dto.getBankNo();
            if (StringUtils.isBlank(dtoBankNo)) {
                jsonResult.remind("银行卡号 不能为空",log);
                return;
            }

            BigDecimal dtoAmount = dto.getAmount();
            if (dtoAmount == null) {
                jsonResult.remind("提现金额 不能为空",log);
                return;
            }

            if (dtoAmount.compareTo(BigDecimal.valueOf(0)) < 0) {
                jsonResult.remind("提现最小金额必须大于0元",log);
                return;
            }

            Long mallId = userInfoDto.mall.getId();
            Long anUserInfoDtomerchantId = userInfoDto.merchant.getId();
            MerchantBank merchantBank = merchantBankRepository.findByMerchantIdAndBankNameAndBankNoAndMallIdAndBankAccountNameAndIsDelete(anUserInfoDtomerchantId, bankName, dtoBankNo, mallId, bankAccountName, Whether.NO);
            if (merchantBank == null) {
                jsonResult.remind("您绑定银行卡填写的信息不完整，为了避免提现失败请修改银行卡绑定信息！",log);
                return;
            }

            MerchantFund merchantFund = merchantFundRepository.findByMallIdAndMerchantId(mallId, anUserInfoDtomerchantId);
            if (merchantFund == null) {
                jsonResult.remind("登录帐号异常,请联系客服人员",log);
                return;
            }
            BigDecimal availableAmount = merchantFund.getAvailableAmount();
            BigDecimal merchantFundAvailableAmount = availableAmount;
            BigDecimal canNotWithdrawAmount = merchantFund.getCanNotWithdrawAmount();
            BigDecimal canWithdrawAmount = merchantFundAvailableAmount.subtract(canNotWithdrawAmount);//减去不可提现金额
            if (dtoAmount.compareTo(canWithdrawAmount) > 0) {
                jsonResult.remind("提现金额不能大于可提现金额",log);
                return;
            }
            // 商家可用金额减少,冻结资金增加
            merchantFund.setAvailableAmount(merchantFundAvailableAmount.subtract(dtoAmount));
            merchantFund.setFrozen(merchantFund.getFrozen().add(dtoAmount));
            merchantFundRepository.save(merchantFund);

            // 申请提现
            MerchantWithdraw applyWithdraw = new MerchantWithdraw();
            String merchantName = userInfoDto.merchant.getName();
            applyWithdraw.setMerchantName(merchantName);
            applyWithdraw.setMallId(mallId);
            applyWithdraw.setMerchantId(anUserInfoDtomerchantId);
            applyWithdraw.setBankAccountName(bankAccountName);
            applyWithdraw.setBankNo(dtoBankNo);
            applyWithdraw.setAmount(dtoAmount);
            applyWithdraw.setBankName(bankName);
            applyWithdraw.setStatus(WithdrawStatus.WAIT_AUDIT);
            String merchantBankBankAccountName = merchantBank.getBankAccountName();
            String merchantBankBankNo =  merchantBank.getBankNo();
            String merchantBankBankName = merchantBank.getBankName();

            applyWithdraw.setBankInfo(merchantBankBankName + "+" + merchantBankBankNo + "+" + merchantBankBankAccountName + "+" + bankBranchName);
            applyWithdraw = merchantWithdrawRepository.save(applyWithdraw);
            // 申请记录
            WithdrawEvent withdrawEvent = new WithdrawEvent();
            withdrawEvent.setStatus(WithdrawStatus.WAIT_AUDIT);
            withdrawEvent.setMallId(mallId);
            withdrawEvent.setApplyWithdrawId(applyWithdraw.getId());
            withdrawEvent.setOperatorId(anUserInfoDtomerchantId);
            withdrawEvent.setProposerId(anUserInfoDtomerchantId);
            withdrawEvent.setWithdrawCrowd(WithdrawCrowd.MERCHANT);
            withdrawEventRepository.save(withdrawEvent);

            //广播消息
            SysMessageHelper.SINGLETON.pushFinanceMsg(SysMessageConstants.M2M_MALL_MERCHANT_APPLY_WITHDRAW, null, mallId,null);
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/apply/withdraw/page 商家提现分页
     * @apiGroup MERCHANT_WITHDRAW
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} beginDate 开始时间
     * @apiParam {String} endDate 结束时间
     * @apiParam {String=ALL("全部"), WAIT_AUDIT("审核中"), PASS("处理中"), FAIL("提现失败"), SUCCESS("提现成功")} status <code>必传参数</code>状态 默认ALL
     *
     * @apiSuccess {date} dateCreated 提现时间
     * @apiSuccess {String} transactionId 流水号 提现成功的时才有流水号
     * @apiSuccess {String=ALL("全部"), WAIT_AUDIT("审核中"), PASS("处理中"), FAIL("提现失败"), SUCCESS("提现成功")} status 状态
     * @apiSuccess {BigDecimal} amount 提现金额
     * @apiSuccess {String} remark 详情说明
     *
     * @apiSuccessExample { json } Success-Response:
     * {
     *  "code": "1",
     *  "desc": "成功"
     *  "data" : {
     *           "dateCreated": "2016-11-08 15:39:10",
     *           "transactionId": "983427598237450924",
     *           "status": "WAIT_AUDIT",
     *           "amount": "23423",
     *           "remark": "提现成功的时才有流水号",
     *      },
     *      ............
     *  }
     */
    @RequestMapping(value = Routes.MERCHANT_APPLY_WITHDRAW_PAGE, method = RequestMethod.GET)
    private JsonResult merchantWithDrawPage(HttpServletRequest request, MerchantWithdrawDto dto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {

            if (StringUtils.isBlank(dto.getStatus()) || !EnumUtils.isValidEnum(WithdrawStatus.class, dto.getStatus())) {
                jsonResult.remind("状态只允许 ALL(\"全部\"), WAIT_AUDIT(\"审核中\"), PASS(\"处理中\"), FAIL(\"提现失败\"), SUCCESS(\"提现成功\")",log);
                return;
            }

            PageResult<MerchantWithdrawDto> pageResult = merchantWithdrawRepository.findMerchantApplyWithdrawPage(userInfoDto.merchant.getId(), userInfoDto.mall.getId(), dto.getBeginDate(), dto.getEndDate(), dto.getStatus(), this.getPage(dto.getPageNo(), dto.getPageSize()));
            pageResult.setUrl(Routes.MERCHANT_APPLY_WITHDRAW_PAGE);
            jsonResult.data = pageResult;
        };
        return doing.go(request ,log);
    }
}
